package cn.jiangjiesheng.bootstrap.commons.utils;

import cn.jiangjiesheng.bootstrap.commons.exception.BeanValidatedFailedException;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.util.*;

/**
 * 基于jdk验证框架对Bean进行属性验证
 *
 * https://www.baeldung.com/javax-validation
 *
 * Created by dev@jiangjiesheng.cn on 2021/8/24  <br/>
 */
@Slf4j
public class BeanValidateUtils {


    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();

    private static final Validator validator = factory.getValidator();

    /**
     * 验证Bean 并返回所有错误信息
     *
     * @param bean
     * @param <T>
     * @return
     */
    public static <T> List<String> validateGetAllErrors(T bean) {
        List<String> errors = new LinkedList<>();
        Set<ConstraintViolation<T>> violations = validator.validate(bean);
        for (ConstraintViolation<T> violation : violations) {
            log.error(violation.getMessage());
            errors.add(violation.getMessage());
        }
        return errors;
    }

    /**
     * 验证bean，并返回第一个错误信息
     * 快速失败：当出现验证不通过，则抛出异常
     *
     * @param bean
     * @param fastFail 快速失败
     * @param <T>
     * @return
     */
    public static <T> String validateGetFirstError(@NonNull T bean, boolean fastFail) {
        Set<ConstraintViolation<T>> violations = validator.validate(bean);
        for (ConstraintViolation<T> violation : violations) {
            if (fastFail){
                throw new BeanValidatedFailedException(violation.getMessage());
            }
            return violation.getMessage();
        }
        return null;
    }

}
